package com.group4;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.group4.service.UserService;
import com.study.util.ResponseResult;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import java.nio.charset.StandardCharsets;
@Slf4j
//@Component
public class GlobalFilter implements org.springframework.cloud.gateway.filter.GlobalFilter, Ordered {

    @Autowired
    private UserService userService;

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        //1，获取请求访问的路径，判断哪些路径需要认证
        String path = exchange.getRequest().getPath().toString();
        log.debug("Path:{}", path);
        //2,不需要认证的直接放行
        if (path.equals("/rbac/user/login")) {
            return chain.filter(exchange);
        }
        //3,需要认证，获取到请求头中的jwt
        String jwt = exchange.getRequest().getHeaders().getFirst("jwt");
        log.debug("JWT:{}", jwt);
        //4，获取不到，直接返回响应，获取得到，发送jwt到用户服务去校验，带出用户id
        if (jwt == null || jwt.trim().isEmpty()) {
            return getVoidMono(exchange);
        } else {
            //访问远程访问校验jwt，结果中带回用户id
            ResponseResult<Integer> result = userService.parseJWT(jwt);

            //5，如果校验通过，将用户id和之前请求中的数据合在一起，发往请求访问的资源
            if (result.getCode() == 200) { //通过
                int id = result.getData();
                ServerHttpRequest mutableReq = exchange.getRequest().mutate().header("id", "" + id).build();
                ServerWebExchange mutableExchange = exchange.mutate().request(mutableReq).build();
                return chain.filter(mutableExchange);
            } else {
                //6，校验不通过，直接返回响应
                return getVoidMono(exchange);
            }
        }
    }

    private Mono<Void> getVoidMono(ServerWebExchange exchange) {
        ServerHttpResponse response = exchange.getResponse();
        ResponseResult<Void> responseResult = new ResponseResult<>(401, "forbid");
        ObjectMapper objectMapper = new ObjectMapper();
        byte[] datas = new byte[0];
        try {
            datas = objectMapper.writeValueAsString(responseResult).getBytes(StandardCharsets.UTF_8);
        } catch (JsonProcessingException e) {
            e.printStackTrace();
        }
        DataBuffer buffer = response.bufferFactory().wrap(datas);
        response.setStatusCode(HttpStatus.UNAUTHORIZED);
        response.getHeaders().add("Content-Type", "application/json;charset=UTF-8");
        return response.writeWith(Mono.just(buffer));
    }

    @Override
    public int getOrder() {
        return -1;
    }
}
